package com.ybear.ybutils.utils.dialog;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntRange;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.StyleRes;

import com.ybear.ybutils.utils.R;
import com.ybear.ybutils.utils.ResUtil;
import com.ybear.ybutils.utils.SysUtil;
import com.ybear.ybutils.utils.Utils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

public class DialogConfig {
    @Retention(RetentionPolicy.SOURCE)
    private @interface Tag {
        String TITLE = "TITLE";
        String BUTTON = "BUTTON";
    }

    private final Context mContext;
    private final android.app.Dialog mDialog;
    private final WindowStyle mStyle;
    private final LinearLayout mLayout;
    private final DialogInit mInit;
    @Nullable
    private DialogButton mDialogButton;
    private boolean enableMeasure = false;

    public DialogConfig(Context context, @StyleRes int themeResId) {
        mContext = context;
        mDialog = new android.app.Dialog( context, themeResId );
        mInit = DialogInit.get();
        mStyle = new WindowStyle( context );
        mLayout = new LinearLayout( mContext );
        initView();
    }

    private void initView() {
        mLayout.setOrientation( LinearLayout.VERTICAL );
        mLayout.setBackgroundColor( Color.TRANSPARENT );
        mLayout.setGravity( Gravity.CENTER );
    }

    /**
     * 设置背景资源
     * @param drawable  资源
     * @return          this
     */
    public DialogConfig setBackgroundDrawable(Drawable drawable) {
        mStyle.setBackgroundDrawable( drawable );
        return this;
    }

    /**
     * 设置背景资源id
     * @param res       资源id
     * @return          this
     */
    public DialogConfig setBackgroundDrawableResource(@DrawableRes int res) {
        mStyle.setBackgroundDrawableResource( res );
        return this;
    }

    public DialogConfig setBackgroundColor(@ColorInt int color) {
        mStyle.setBackgroundColor( color );
        return this;
    }

    /**
     * 设置圆角
     * @param radius    圆滑度
     * @return          this
     */
    public DialogConfig setCornerRadius(@IntRange(from = 0) int radius) {
        mStyle.setCornerRadius( radius );
        return this;
    }

    /**
     * 设置圆角
     * @param radii     控制每个角的圆滑度，每两组表示一个角度，一共八组，即：radii.length = 8
     * @return          this
     */
    public DialogConfig setCornerRadii(float[] radii) {
        mStyle.setCornerRadii( radii );
        return this;
    }

    /**
     * 设置透明背景
     * @return          this
     */
    public DialogConfig transparentBackground() {
        return setBackgroundDrawableResource( R.color.transparent );
    }

    /**
     * 设置对话框之外的透明度
     * @param dimAmount     0.0 ~ 1.0
     * @return              this
     */
    public DialogConfig setDimAmount(float dimAmount) {
        mStyle.setDimAmount( dimAmount );
        return this;
    }

    /**
     * 设置默认的对话框之外的透明度。默认：0.6
     * @return              this
     */
    public DialogConfig defaultDimAmount() { return setDimAmount( 0.6F ); }

    /**
     * 设置对话框之外的透明度为透明。
     * @return              this
     */
    public DialogConfig transparentDimAmount() { return setDimAmount( 0F ); }

    /**
     * 显示位置
     * @param gravity   {@link Gravity}
     * @return          this
     */
    public DialogConfig setGravity(int gravity) {
        mStyle.setGravity( gravity );
        return this;
    }

    public DialogConfig setAnimations(@StyleRes int resId) {
        mStyle.setAnimations( resId );
        return this;
    }

    /**
     * 中间淡入淡出动画
     * @return          this
     */
    public DialogConfig animOfCenterAlpha() {
        setGravity( Gravity.CENTER );
        return setAnimations( R.style.dialogAnimOfCenterAlpha );
    }

    /**
     * 中间顶部一小段距离进出动画
     * @return          this
     */
    public DialogConfig animOfCenterTopTranslate() {
        setGravity( Gravity.CENTER );
        return setAnimations( R.style.dialogAnimOfCenterTopTranslate );
    }

    /**
     * 中间底部一小段距离进出动画
     * @return          this
     */
    public DialogConfig animOfCenterBottomTranslate() {
        setGravity( Gravity.CENTER );
        return setAnimations( R.style.dialogAnimOfCenterBottomTranslate );
    }

    /**
     * 顶部进出动画
     * @return          this
     */
    public DialogConfig animOfTopTranslate() {
        setGravity( Gravity.CENTER_HORIZONTAL | Gravity.TOP );
        return setAnimations( R.style.dialogAnimOfTopTranslate );
    }

    /**
     * 底部进出动画
     * @return          this
     */
    public DialogConfig animOfBottomTranslate() {
        setGravity( Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM );
        return setAnimations( R.style.dialogAnimOfBottomTranslate );
    }

    /**
     * 描边
     * @param width     宽度
     * @param color     颜色
     * @return          this
     */
    public DialogConfig setStroke(int width, @ColorInt int color) {
        mStyle.setStroke( width, color );
        return this;
    }

    /**
     * 对话框形状
     * @param shape     {@link com.ybear.ybutils.utils.dialog.WindowStyle.Shape}
     * @return          this
     */
    public DialogConfig setShape(@WindowStyle.Shape int shape) {
        mStyle.setShape( shape );
        return this;
    }

//    private static final int REQUEST_CODE_SYSTEM_DIALOG = 3308;

    /**
     * 系统级对话框
     * @param enable    是否启用为系统级对话框
     * @return          this
     */
    public DialogConfig setSystemDialog(Activity activity, boolean enable) {
        mStyle.setSystemDialog( enable );

        //6.0之后需要用户手动打开<允许显示在其他应用的上层>这个选项
        if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
            //是否已经打开过
            if( Settings.canDrawOverlays(activity) ) return this;
            Intent intent = new Intent( Settings.ACTION_MANAGE_OVERLAY_PERMISSION );
            intent.setData( Uri.parse( "package:" + mContext.getPackageName() ) );
            activity.startActivity( intent );
//            activity.startActivityForResult( intent, REQUEST_CODE_SYSTEM_DIALOG );
        }

        return this;
    }

    /**
     * 设置确定按钮点击事件监听器
     * @param positiveText  按钮文本内容
     * @param style         按钮样式
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnPositiveButtonListener(@Nullable String positiveText,
                                                    @Nullable TextStyle style,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnPositiveListener( positiveText, style, l );
        return this;
    }

    /**
     * 设置确定按钮点击事件监听器
     * @param positiveText   文本资源
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnPositiveButtonListener(@Nullable String positiveText,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnPositiveListener( positiveText, l );
        return this;
    }

    /**
     * 设置确定按钮点击事件监听器
     * @param positiveText   文本资源
     * @return              this
     */
    public DialogConfig setOnPositiveButtonListener(@Nullable String positiveText) {
        getDialogButton().setOnPositiveListener( positiveText );
        return this;
    }

    /**
     * 设置确定按钮点击事件监听器
     * @param positiveRes   文本资源
     * @param style         按钮样式
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnPositiveButtonListener(@StringRes int positiveRes,
                                                    @Nullable TextStyle style,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnPositiveListener( positiveRes, style, l );
        return this;
    }

    /**
     * 设置确定按钮点击事件监听器
     * @param positiveRes   文本资源
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnPositiveButtonListener(@StringRes int positiveRes,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnPositiveListener( positiveRes, l );
        return this;
    }

    /**
     * 设置确定按钮点击事件监听器
     * @param positiveRes   文本资源
     * @return              this
     */
    public DialogConfig setOnPositiveButtonListener(@StringRes int positiveRes) {
        getDialogButton().setOnPositiveListener( positiveRes );
        return this;
    }

    /**
     * 设置确定按钮点击事件监听器
     * @param positiveRes   文本资源
     * @param style         按钮样式
     * @return              this
     */
    public DialogConfig setOnPositiveButtonListener(@StringRes int positiveRes,
                                                    @Nullable TextStyle style) {
        getDialogButton().setOnPositiveListener( positiveRes, style );
        return this;
    }

    /**
     * 设置确定按钮点击事件监听器
     * @param style         按钮样式
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnPositiveButtonListener(@Nullable TextStyle style,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnPositiveListener( style, l );
        return this;
    }

    /**
     * 设置确定按钮点击事件监听器
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnPositiveButtonListener(@Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnPositiveListener( l );
        return this;
    }

    /**
     * 设置取消按钮点击事件监听器
     * @param negativeText  按钮文本内容
     * @param style         按钮样式
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnNegativeButtonListener(@Nullable String negativeText,
                                                    @Nullable TextStyle style,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnNegativeListener( negativeText, style, l );
        return this;
    }

    /**
     * 设置取消按钮点击事件监听器
     * @param negativeText  按钮文本内容
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnNegativeButtonListener(@Nullable String negativeText,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnNegativeListener( negativeText, l );
        return this;
    }

    /**
     * 设置取消按钮点击事件监听器
     * @param negativeText  按钮文本内容
     * @return              this
     */
    public DialogConfig setOnNegativeButtonListener(@Nullable String negativeText) {
        getDialogButton().setOnNegativeListener( negativeText );
        return this;
    }

    /**
     * 设置取消按钮点击事件监听器
     * @param negativeRes   文本资源
     * @param style         按钮样式
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnNegativeButtonListener(@StringRes int negativeRes,
                                                    @Nullable TextStyle style,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnNegativeListener( negativeRes, style, l );
        return this;
    }

    /**
     * 设置取消按钮点击事件监听器
     * @param negativeRes   文本资源
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnNegativeButtonListener(@StringRes int negativeRes,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnNegativeListener( negativeRes, l );
        return this;
    }

    /**
     * 设置取消按钮点击事件监听器
     * @param negativeRes   文本资源
     * @return              this
     */
    public DialogConfig setOnNegativeButtonListener(@StringRes int negativeRes) {
        getDialogButton().setOnNegativeListener( negativeRes );
        return this;
    }

    /**
     * 设置取消按钮点击事件监听器
     * @param negativeRes   文本资源
     * @param style         按钮样式
     * @return              this
     */
    public DialogConfig setOnNegativeButtonListener(@StringRes int negativeRes,
                                                    @Nullable TextStyle style) {
        getDialogButton().setOnNegativeListener( negativeRes, style );
        return this;
    }

    /**
     * 设置取消按钮点击事件监听器
     * @param style         按钮样式
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnNegativeButtonListener(@Nullable TextStyle style,
                                                    @Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnNegativeListener( style, l );
        return this;
    }

    /**
     * 设置取消按钮点击事件监听器
     * @param l             事件监听器
     * @return              this
     */
    public DialogConfig setOnNegativeButtonListener(@Nullable DialogInterface.OnClickListener l) {
        getDialogButton().setOnNegativeListener( l );
        return this;
    }

    /**
     * 创建普通对话框
     * @param layoutRes     内容View id
     * @param params        View的布局参数
     * @return              this
     */
    public DialogOption create(@LayoutRes int layoutRes, @Nullable ViewGroup.LayoutParams params) {
        View v = loadView( layoutRes );
        if( params != null ) v.setLayoutParams( params );
        return build( getDialogLayoutParams() );
    }

    /**
     * 创建普通对话框
     * @param layoutRes     内容View id
     * @param width         View宽度
     * @param height        View高度
     * @return              this
     */
    public DialogOption create(@LayoutRes int layoutRes, int width, int height) {
        return create( layoutRes, new ViewGroup.LayoutParams( width, height ) );
    }

    /**
     * 创建普通对话框
     * @param layoutRes     内容View id
     * @return              this
     */
    public DialogOption create(@LayoutRes int layoutRes) { return create( layoutRes, null ); }

    /**
     * 创建普通对话框
     * @param view          内容View
     * @param params        View的布局参数
     * @return              this
     */
    public DialogOption create(@Nullable View view, @Nullable ViewGroup.LayoutParams params) {
        return buildView( view, params, getDialogLayoutParams() );
    }

    /**
     * 创建普通对话框
     * @param view          内容View
     * @param width         View宽度
     * @param height        View高度
     * @return              this
     */
    public DialogOption create(@NonNull View view, int width, int height) {
        return create( view, new ViewGroup.LayoutParams( width, height ) );
    }

    /**
     * 创建普通对话框
     * @param view          内容View
     * @return              this
     */
    public DialogOption create(@Nullable View view) { return create( view, null ); }

    /**
     * 创建普通对话框
     * @return              this
     */
    public DialogOption create() {
        if( mStyle.getCornerRadius() == -1 ) setCornerRadius( 4 );
        return create( null, null );
    }

    /**
     * 创建自由对话框，宽高不受限制
     * @param layoutRes     内容View id
     * @param lp            View的布局参数
     * @return              this
     */
    public DialogOption createOfFree(@LayoutRes int layoutRes,
                                     @Nullable ViewGroup.LayoutParams lp) {
        View v = loadView( layoutRes );
        if( lp != null ) v.setLayoutParams( lp );
        return build( null );
    }

    /**
     * 创建自由对话框，宽高不受限制
     * @param layoutRes     内容View id
     * @param width         View宽度
     * @param height        View高度
     * @return              this
     */
    public DialogOption createOfFree(@LayoutRes int layoutRes, int width, int height) {
        return createOfFree( layoutRes, new ViewGroup.LayoutParams( width, height ) );
    }

    /**
     * 创建自由对话框，宽高不受限制
     * @param layoutRes     内容View id
     * @return              this
     */
    public DialogOption createOfFree(@LayoutRes int layoutRes) {
        return createOfFree( layoutRes, null );
    }

    /**
     * 创建自由对话框，宽高不受限制
     * @param view          内容View
     * @param lp        view布局参数
     * @return              this
     */
    public DialogOption createOfFree(@Nullable View view, @Nullable ViewGroup.LayoutParams lp) {
        return buildView( view, lp, null );
    }

    /**
     * 创建自由对话框，宽高不受限制
     * @param view          内容View
     * @param width         View宽度
     * @param height        View高度
     * @return              this
     */
    public DialogOption createOfFree(@NonNull View view, int width, int height) {
        return createOfFree( view, new ViewGroup.LayoutParams( width, height ) );
    }

    /**
     * 创建自由对话框，宽高不受限制
     * @param view          内容View
     * @return              this
     */
    public DialogOption createOfFree(@NonNull View view) { return createOfFree( view, null ); }

    /**
     * 创建自由对话框，宽高不受限制
     * @return              this
     */
    public DialogOption createOfFree() { return createOfFree( null, null ); }

    /**
     * 创建普通对话框，覆盖内容View的布局参数为{@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
     * @param layoutRes     内容View
     * @return              this
     */
    public DialogOption createOfMatch(@LayoutRes int layoutRes) {
        View v = loadView( layoutRes );
        v.setLayoutParams( getMatchLayoutParams() );
        return build( getDialogLayoutParams() );
    }

    /**
     * 创建普通对话框，覆盖内容View的布局参数为{@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
     * @param view          内容View
     * @return              this
     */
    public DialogOption createOfMatch(@Nullable View view) {
        return buildView( view, getMatchLayoutParams(), getDialogLayoutParams() );
    }

    /**
     * 创建自由对话框，创建自由对话框，宽高不受限制
     * 覆盖内容View的布局参数为{@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
     * @param view          内容View
     * @return              this
     */
    public DialogOption createOfMatchAndFree(@Nullable View view) {
        return buildView( view, getMatchLayoutParams(), null );
    }

    /**
     * 创建自由对话框，创建自由对话框，宽高不受限制
     * 覆盖内容View的布局参数为{@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}
     * @param layoutRes     内容View
     * @return              this
     */
    public DialogOption createOfMatchAndFree(@LayoutRes int layoutRes) {
        View v = loadView( layoutRes );
        v.setLayoutParams( getMatchLayoutParams() );
        return build( null );
    }

    /**
     * 创建普通对话框
     * @param create    通过封装类创建
     * @return          this
     */
    public DialogOption create(@NonNull Create<? extends View> create) {
        ViewGroup.LayoutParams lp = create.getLayoutParams();
        if( create.isFree() ) {
            if( lp == null ) {
                return createOfFree( create.getLayout(), create.getWidth(), create.getHeight() );
            } else {
                return createOfFree( create.getLayout(), lp );
            }
        }else {
            if( lp == null ) {
                return create( create.getLayout(), create.getWidth(), create.getHeight() );
            } else {
                return create( create.getLayout(), lp );
            }
        }
    }

    /**
     * 设置标题。{@link Dialog#getWindow()}
     * @param title         标题内容
     * @param titleColor    标题颜色
     * @return              this
     */
    @Deprecated
    public DialogConfig setTitleOfWindow(String title, @ColorInt int titleColor) {
        Window w = getWindow();
        if( w == null ) return setTitle( title );
        w.setTitle( title );
        if( titleColor != -1 ) w.setTitleColor( titleColor );
        return this;
    }

    /**
     * 设置标题。{@link Dialog#getWindow()}
     * @param title     标题内容
     * @return          this
     */
    @Deprecated
    public DialogConfig setTitleOfWindow(String title) {
        return setTitleOfWindow( title, -1 );
    }

    /**
     * 设置标题
     * @param title     标题内容
     * @param style     文本样式
     * @return          this
     */
    public DialogConfig setTitle(String title, @NonNull TextStyle style) {
        if( Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 ) {
            int color = style.getTextColorInt();
            if( color == -1 ) color = ResUtil.getColor( mContext, style.getTextColor() );
            return setTitleOfWindow( title, color );
        }else {
            TextView tv = style.getTextView( mContext, title );
            tv.setTag( Tag.TITLE );
            tv.setLayoutParams( getDefaultLayoutParams() );
            return addView( tv );
        }
    }

    /**
     * 设置标题
     * @param resId     标题内容
     * @param style     文本样式
     * @return          this
     */
    public DialogConfig setTitle(@StringRes int resId, @NonNull TextStyle style) {
        return setTitle( getString( resId ), style );
    }

    /**
     * 设置标题
     * @param title     标题内容
     * @return          this
     */
    public DialogConfig setTitle(String title) { return setTitle(title, getDefTitleTextStyle()); }

    /**
     * 设置标题
     * @param resId     标题内容
     * @return          this
     */
    public DialogConfig setTitle(@StringRes int resId) { return setTitle( getString( resId ) ); }

    /**
     * 设置显示内容
     * @param msg       消息内容
     * @param style     文本样式
     * @return          this
     */
    public DialogConfig setMessage(String msg, @NonNull TextStyle style) {
        TextView tv = style.getTextView( mContext, msg );
        tv.setLayoutParams( getDefaultLayoutParams() );
        return addView( tv );
    }

    /**
     * 设置显示内容
     * @param resId     消息内容
     * @param style     文本样式
     * @return          this
     */
    public DialogConfig setMessage(@StringRes int resId, @NonNull TextStyle style) {
        return setMessage( getString( resId ), style );
    }

    /**
     * 设置显示内容
     * @param msg       消息内容
     * @return          this
     */
    public DialogConfig setMessage(String msg) { return setMessage(msg, getDefMessageTextStyle()); }

    /**
     * 设置显示内容
     * @param resId     消息内容
     * @return          this
     */
    public DialogConfig setMessage(@StringRes int resId) {
        return setMessage( getString( resId ) );
    }

    /**
     * 测量内容View。测量传入布局的实际大小。如果也传入了布局参数，则布局参数会失效。
     * 该方法主要解决设计的布局设置 {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT} 或者
     * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} 无效时使用。
     * @return          this
     */
    public DialogConfig measure() {
        enableMeasure = true;
        return this;
    }

    /**
     * 获取默认标题文本样式
     * @return  文本样式
     */
    public TextStyle getDefTitleTextStyle() {
        return new TextStyle()
                .setTextColor( mInit.getDefTitleColor() )
                .setTextColorInt( mInit.getDefTitleColorInt() )
                .setTextSize( mInit.getDefTitleTextSize() )
                .setPadding(
                        Utils.dp2Px(mContext, mInit.getDefTitleLeftPadding()),
                        Utils.dp2Px(mContext, mInit.getDefTitleTopPadding()),
                        Utils.dp2Px(mContext, mInit.getDefTitleRightPadding()),
                        Utils.dp2Px(mContext, mInit.getDefTitleBottomPadding())
                );
    }
    /**
     * 获取默认内容文本样式
     * @return  文本样式
     */
    public TextStyle getDefMessageTextStyle() {
        int pTop;
        if( Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1 ) {
            pTop = 16;
        }else {
            pTop = mInit.getDefMessageBottomPadding();
        }
        return new TextStyle()
                .setTextColorInt( Color.BLACK )
                .setGravity( Gravity.START | Gravity.TOP )
                .setMaxLines( 8 )
                .setEnableHorizontalScroll( true )
                .setPadding(
                        Utils.dp2Px( mContext, mInit.getDefMessageLeftPadding() ),
                        Utils.dp2Px( mContext, pTop ),
                        Utils.dp2Px( mContext, mInit.getDefMessageRightPadding() ),
                        Utils.dp2Px( mContext, mInit.getDefMessageBottomPadding() )
                );
    }

    /**
     * 获取Dialog的Window
     * @return  {@link Dialog#getWindow()}
     */
    public Window getWindow() { return mDialog.getWindow(); }


    public LinearLayout getRoot() { return mLayout; }

    private DialogConfig addView(View view, ViewGroup.LayoutParams lp) {
        if( lp == null ) {
            mLayout.addView( view );
        }else {
            mLayout.addView( view, lp );
        }
        return this;
    }
    private DialogConfig addView(View view) { return addView( view, null ); }

    private DialogOption build(@Nullable ViewGroup.LayoutParams lp) {
        @NonNull
        Window w;
        if( mDialogButton != null ) {
            View v = mDialogButton.createButton();
            if( v != null ) {
                v.setTag( Tag.BUTTON );
                v.setLayoutParams( getDefaultLayoutParams() );
                addView( v );
            }
        }

        //设置View
        mDialog.setContentView( mLayout, getMatchLayoutParams() );

        //设置Window
        if( ( w = getWindow() ) != null ) {
            //构建属性
            buildAttributes( w, lp );

            //显示位置
            w.setGravity( mStyle.getGravity() );

            //对话框背景
            if( mStyle.getBackgroundDrawableResource() == 0 ) {
                w.setBackgroundDrawable( mStyle.getBackgroundDrawable() );
            }else {
                w.setBackgroundDrawableResource( mStyle.getBackgroundDrawableResource() );
            }

            //背景透明度
            if( mStyle.getDimAmount() != -1F ) {
                w.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND );
                w.setDimAmount( mStyle.getDimAmount() );
            }

            //动画
            if( mStyle.getAnimations() != 0 ) {
                w.setWindowAnimations( mStyle.getAnimations() );
            }

            //构建系统级对话框
            buildSystemDialog( w );
        }
        return new DialogOption( mDialog );
    }

    /**
     * 设置属性
     * @param w     {@link Window}
     * @param lp    {@link android.view.ViewGroup.LayoutParams}
     */
    private void buildAttributes(Window w, @Nullable ViewGroup.LayoutParams lp) {
        WindowManager.LayoutParams wLP = w.getAttributes();
        int matchParent = ViewGroup.LayoutParams.MATCH_PARENT;
        int wrapContent = ViewGroup.LayoutParams.WRAP_CONTENT;

        //使用测量的高度
        if( enableMeasure ) {
            /* 测量宽高 */
            mLayout.measure( 0, 0 );
            wLP.width = mLayout.getMeasuredWidth();
            wLP.height = mLayout.getMeasuredHeight();
            w.setAttributes( wLP );
            return;
        }

        //自定义宽高
        if( lp != null ) {
            wLP.width = lp.width;
            wLP.height = lp.height;
            //自定义控件情况下需要额外加上标题和按钮的高度
            if( lp.height != matchParent && lp.height != wrapContent ) {
                for (int i = 0; i < mLayout.getChildCount(); i++) {
                    View v = mLayout.getChildAt( i );
                    Object tag = v.getTag();
                    if( Tag.TITLE.equals( tag ) || Tag.BUTTON.equals( tag ) ) {
                        v.measure( 0, 0 );
                        wLP.height += v.getMeasuredHeight();
                    }
                }
            }
            w.setAttributes( wLP );
            return;
        }

        /* 默认宽高 */
        wLP.width = matchParent;
        wLP.height = wrapContent;
        w.setAttributes( wLP );
    }

    /**
     * 设置系统级对话框
     * @param w     {@link Window}
     */
    private void buildSystemDialog(Window w) {
        if( !mStyle.isSystemDialog() ) return;
        if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ) {
            //8.0适配
            w.setType( WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY );
        }else {
            //之前的适配
            w.setType( WindowManager.LayoutParams.TYPE_SYSTEM_ALERT );
        }
    }

    /**
     * 创建/获取对话框的按钮
     * @return  对话框按钮
     */
    @NonNull
    private DialogButton getDialogButton() {
        if( mDialogButton == null ) mDialogButton = new DialogButton( mContext, mDialog );
        return mDialogButton;
    }

    private String getString(int resId) { return ResUtil.getString( mContext, resId ); }

    /**
     * 获取默认布局参数
     * @return  参数
     */
    private ViewGroup.LayoutParams getDefaultLayoutParams() {
        return new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
        );
    }

    private ViewGroup.LayoutParams getDialogLayoutParams() {
        return new ViewGroup.LayoutParams(
                (int)( SysUtil.getScreenWidth(mContext) / 1.2F ),
                ViewGroup.LayoutParams.WRAP_CONTENT
        );
    }

    private ViewGroup.LayoutParams getMatchLayoutParams() {
        return new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
        );
    }

    private View loadView(@LayoutRes int layoutRes) {
        return View.inflate( mContext, layoutRes, mLayout );
    }

    /**
     * 创建对话框
     * @param view              内容View
     * @param viewParams        内容View的布局参数
     * @param windowParams      父布局的布局参数
     * @return                  this
     */
    private DialogOption buildView(@Nullable View view,
                                   @Nullable ViewGroup.LayoutParams viewParams,
                                   @Nullable ViewGroup.LayoutParams windowParams) {
        if( view != null ) {
            if( viewParams != null ) {
                addView( view, viewParams );
            }else {
                addView( view );
            }
        }
        return build( windowParams );
    }
}